package cn.melonlib.download.comp.service.impl;

import cn.melonlib.download.comp.service.DownloadService;
import cn.melonlib.download.comp.service.StreamResource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@ConditionalOnProperty(value = "web.stream.download.type",havingValue = "range",matchIfMissing = true)
public class RangeDownloadService implements DownloadService {

    private final static Pattern RANGE_REGEX=Pattern.compile("bytes=(\\d+)-(\\d+)?");
    @Override
    public void download(HttpServletRequest request, HttpServletResponse response, String name, Long size, String contentType, InputStream in) throws IOException {
//        RandomAccessFile f=new RandomAccessFile();
        String range=request.getHeader("Range");
        response.setHeader("Accept-Ranges","bytes");
        response.setHeader("Location", URLEncoder.encode(name, StandardCharsets.UTF_8));
        response.setHeader("Content-Disposition", "filename*=UTF-8''" + URLEncoder.encode(name, StandardCharsets.UTF_8));
        response.setContentLengthLong(size);
        response.setContentType(contentType);
        Matcher m=RANGE_REGEX.matcher(StringUtils.defaultString(range,""));
        if(m.matches()){

            long start=Long.parseLong(m.group(1));
            long defaultBytes=(10<<20<size-start)?start+10<<20:size;
            long end=StringUtils.isBlank(m.group(2))?size:Long.parseLong(m.group(2));
            if(end == size){
                response.setStatus(HttpServletResponse.SC_OK);
            }else{
                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            }
            response.setHeader("Content-Range","bytes="+start+"-"+end);
            System.out.println(start + ":" + end);
            try(OutputStream out=response.getOutputStream()) {
                StreamUtils.copyRange(in, out,start,end);
            }catch (Exception e){
                e.printStackTrace();
            }
        }else{
            try(OutputStream out=response.getOutputStream()) {
                StreamUtils.copyRange(in, out,0,size);
            }
        }
        //bytes=3970957312-3972005887
    }
}
